using Microsoft.EntityFrameworkCore;
using net_work.Common.Request;
using net_work.Common.Result;
using net_work.Config;
using net_work.Data.DTO.Sys;
using net_work.Data.Entity.Sys;
using net_work.Data.VO.Sys;
using net_work.IRepository.Sys;

namespace net_work.Repository.Sys;

public class AdministrativeClassRepository(ApplicationDbContext dbContext)
    : Repository<AdministrativeClass>(dbContext), IAdministrativeClassRepository
{
    public async Task<long> InsertAsync(AdministrativeClassAddRequest administrativeClassAddRequest)
    {
        var existingAdministrativeClass =
            await dbContext.AdministrativeClasses.IgnoreQueryFilters().FirstOrDefaultAsync(x =>
                x.ClassName == administrativeClassAddRequest.ClassName);
        if (existingAdministrativeClass != null)
        {
            return -1;
        }

        var newAdministrativeClass = new AdministrativeClass
        {
            ClassName = administrativeClassAddRequest.ClassName,
            ClassGrade = administrativeClassAddRequest.ClassGrade,
            ClassNum = 0,
            HeadTeacherId = administrativeClassAddRequest.HeadTeacherId,
            CollegeId = administrativeClassAddRequest.CollegeId,
            Remark = administrativeClassAddRequest.Remark
        };
        await dbContext.AdministrativeClasses.AddAsync(newAdministrativeClass);
        await dbContext.SaveChangesAsync();
        return newAdministrativeClass.Id;
    }

    public async Task<bool> UpdateAsync(AdministrativeClassUpdateRequest administrativeClassUpdateRequest)
    {
        var administrativeClasses = await dbContext.AdministrativeClasses
            .IgnoreQueryFilters()
            .Where(x => x.ClassName == administrativeClassUpdateRequest.ClassName ||
                        x.Id == administrativeClassUpdateRequest.Id)
            .ToListAsync();

        var conflictAdministrativeClass =
            administrativeClasses.FirstOrDefault(x => x.Id != administrativeClassUpdateRequest.Id);
        if (conflictAdministrativeClass != null)
        {
            return false;
        }

        var existingAdministrativeClass =
            administrativeClasses.FirstOrDefault(x => x.Id == administrativeClassUpdateRequest.Id);
        if (existingAdministrativeClass == null)
        {
            return false;
        }

        existingAdministrativeClass.Remark = administrativeClassUpdateRequest.Remark;
        existingAdministrativeClass.ClassName = administrativeClassUpdateRequest.ClassName;
        existingAdministrativeClass.ClassGrade = administrativeClassUpdateRequest.ClassGrade;
        existingAdministrativeClass.ClassNum = existingAdministrativeClass.ClassNum;
        existingAdministrativeClass.HeadTeacherId = administrativeClassUpdateRequest.HeadTeacherId;
        existingAdministrativeClass.CollegeId = administrativeClassUpdateRequest.CollegeId;

        await dbContext.SaveChangesAsync();
        return true;
    }

    public Task<PagedResult<AdministrativeClassResult>> GetAdministrativeClassPagedAsync(PagedRequest request)
    {
        var query = from administrativeClass in dbContext.AdministrativeClasses
            join college in dbContext.Colleges on administrativeClass.CollegeId equals college.Id into collegeJoin
            from college in collegeJoin.DefaultIfEmpty()
            join teacher in dbContext.Teachers on administrativeClass.HeadTeacherId equals teacher.Id into teacherJoin
            from teacher in teacherJoin.DefaultIfEmpty()
            join person in dbContext.People on teacher.PsnId equals person.Id into personJoin
            from person in personJoin.DefaultIfEmpty()
            select new AdministrativeClassResult
            {
                Id = administrativeClass.Id,
                ClassName = administrativeClass.ClassName,
                ClassGrade = administrativeClass.ClassGrade,
                ClassNum = administrativeClass.ClassNum,
                HeadTeacherId = administrativeClass.HeadTeacherId,
                HeadTeacherName = person.PsnName,
                CollegeId = administrativeClass.CollegeId,
                CollegeName = college.ColleName,
                Remark = administrativeClass.Remark,
                CreatedBy = administrativeClass.CreatedBy,
                CreatedTime = administrativeClass.CreatedTime,
                UpdatedBy = administrativeClass.UpdatedBy,
                UpdatedTime = administrativeClass.UpdatedTime,
                DelFlag = administrativeClass.DelFlag
            };

        return GetPagedQueryResultAsync(query, request);
    }

    public async Task<bool> UpdateClassNumAsync(long classId, long classNum)
    {
        var administrativeClass = await dbContext.AdministrativeClasses.FindAsync(classId);
        if (administrativeClass == null)
        {
            return false;
        }

        administrativeClass.ClassNum = classNum;
        await dbContext.SaveChangesAsync();
        return true;
    }
}